home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr52 / nguide.zip / NGUIDE.ART
Text File  |  1993-04-01  |  88KB  |  1,601 lines

  1. *Clipper in Network, tips, suggestions...
  2.  
  3.                   Clipper in Network, tips, suggestions...
  4.                                     alias
  5.                     Network Guide for Clipper programmer
  6.                       ────────────────────────────────
  7.                                      by
  8.                                Daniel Docekal
  9.  
  10.  
  11. Clipper application in network is something that should work on first moment
  12. of start if some guidelines are followed and some conditions fulfilled. If
  13. program you are writing is written with record and file locking and is taking
  14. care of everything that can happened in file sharing, there shouldn't be
  15. problem to run it and use it. Reality is often different, many problems can
  16. rise out from nowhere which will prevent your application from running or
  17. will give difficulties to application's run. What this article will try is to
  18. give helpful hand to those who are starting in networking with Clipper, but
  19. also for those who are swimming in problems with written Clipper application.
  20. I would like to ask anybody who wishes to contribute in this Network Clipper
  21. guideline to do so, then i can collect opinions and release them in new
  22. edition.
  23.  
  24. NETWORK APPLICATION──┐
  25. ─────────────────────┘
  26.  
  27. Network application in general must follow idea that it's not only one
  28. program running at the same time. Network application which is using ANY from
  29. resources of network must take good care of fact that in most cases it WILL
  30. SHARE them with other applications running at the same time and requiring
  31. access to the same resources. In most cases it's matter of programming
  32. languages to give tools for networking rather than programmers knowledge.
  33. Clipper is high level programming language in difference from assembler or
  34. basic of C language, therefore is expected that networking behavior will be
  35. covered with filling needs.
  36.  
  37. NETWORK──┐
  38. ─────────┘
  39.  
  40. Network is something most horrible and bad for every programmer, nightmare
  41. like environment with every problem hidden after not sufficient knowledge and
  42. not experienced people around. Believe or not, it's right definition of
  43. network for beginning. Users of network which are in most cases not even good
  44. equipped with knowledge of MS DOS are of course able to broke all rules which
  45. logically thinking programmer will have in mind when programming, therefore
  46. programmer must start thinking like average (or even, like under average)
  47. users. Difficulty of this mind change is paid in most cases by application
  48. which is created with best wishes and is ending SOMETIME in troubles.
  49.  
  50. CLIPPER──┐
  51. ─────────┘
  52.  
  53. Clipper is programming language offering enough to start writing network
  54. application. General guidelines are very simple:
  55.  
  56. ┌╖  if database file has to be used at one time by MORE users (workstations
  57. ╘╝  will be used in all next text) then it must be opened as SHAREABLE
  58.  
  59.     What this is requiring is very simple, either USE..SHARED or
  60.     SET EXCLUSIVE OFF before all USE which are not equipped with SHARED nor
  61.     EXCLUSIVE keyword.
  62.  
  63.     │ Experienced users are probably falling away, but please don't rather
  64.     │ skip those basic informations, later are coming more handy ones.
  65.  
  66.     What can be often source of problems:
  67.  
  68.     WS-A has file FILE opened as EXCLUSIVE and WS-B is trying top open it
  69.     by USE (of any form). As far as WS-A has it exclusive there is no way
  70.     how to access this file.
  71.  
  72.     WS-A has file opened as SHARED and WS-B is trying open it as EXCLUSIVE
  73.     which cannot because may not gain EXCLUSIVE access to already SHARED
  74.     file.
  75.  
  76.     WS-A has file opened with fopen() (or just by program like Norton
  77.     Commander), no any other workstation is able to access file.
  78.  
  79.     USE command is NOT well made for network operations. it's requiring
  80.     little effort from programmer because needs test of NETERR() function
  81.     after USE if required operation was finished:
  82.  
  83.     │   USE ADRES SHARED NEW
  84.     │   IF !NETERR()
  85.     │       SET INDEX TO ADRESI1,ADRESI2,ADRESI3
  86.     │   ELSE
  87.     │       //  error situation
  88.     │   ENDIF
  89.  
  90.     This is base fragment of opening a files in network. ANY application
  91.     can be built with this method because it WILL work perfect even without
  92.     network and what it also will - work inside of MS WINDOWs or any other
  93.     multitasking software which also requires network methods of file access.
  94.  
  95.     Here we do have of course little problem, USE attempt is just made one
  96.     time and not repeated again and again for case that condition will change
  97.     and file will be ready for opening. That's of course trouble of
  98.     programmer which must know in what conditions will program run. 24hours
  99.     running mail server should again and again try to open files, but user
  100.     program just shall only tell to user about problem and then exit. It's
  101.     user's decision what to do, call supervisor or try it later.
  102.  
  103. ┌╖  if any file has to be used at one time by MORE workstations then it must
  104. ╘╝  be opened also in SHARED mode.
  105.  
  106.     This must be based on FOPEN() function which IS allowing some MORE
  107.     attributes of open
  108.  
  109.         0               FO_READ              Open for reading (default)
  110.         1               FO_WRITE             Open for writing
  111.         2               FO_READWRITE         Open for reading or writing
  112.     addition which should be done:
  113.         16              FO_DENYALL           Not allow ANYBODY else access
  114.         32              FO_DENYWRITE         Write access of others denied
  115.         32+16           FO_DENYREAD          Read access of others denied
  116.         64              FO_DENYNONE          Full access of others permitted
  117.  
  118.     This extension of fopen() function will allow to control if two
  119.     workstations can simultaneously access the same text file (for example).
  120.  
  121. ┌╖  Any updates to database files are requiring record or file locking,
  122. ╘╝  unless database is opened in EXCLUSIVE mode.
  123.  
  124.     SHARED open database is suitable for READING records but not for
  125.     writing. Basic conflict which can happened when two workstations will
  126.     try to change database is that both of them will come into the very
  127.     same record. It's something that may not be. Therefore RECORD LOCK is
  128.     required before ANY operation which CHANGES value of FIELD in RECORD
  129.     of database. Record lock is in general result of RLOCK() function which
  130.     will TRY to lock record, but it must not be successful. In general
  131.     record locking mechanism should follow:
  132.  
  133.     -   try to lock record and if it goes fine just continue with
  134.         operations
  135.     -   if request for locking failed there are several possibilities:
  136.  
  137.         -   try it for INFINITE time
  138.         -   try it until user will stop it with STOP key
  139.         -   try it for DEFINED time (let say one minute)
  140.         -   try it for DEFINED number of attempts
  141.         -   try FIX reason of failed record lock request
  142.         -   stop immediate and tell user and not continue
  143.  
  144.         In general there are combinations usual given by:
  145.  
  146.         -   it's trying some time and user can stop it by pressing
  147.             STOP key
  148.  
  149.         Many from third part add-ons are offering replacement for
  150.         rlock() function, therefore let them to do job. BBS systems
  151.         and Compuserve will have for sure enough of those examples...
  152.  
  153.     The same as above written is valid about locking of WHOLE file. Locking
  154.     of record is needed in case of operation which will change ONE record,
  155.     locking of FILE is needed on operation which will be changing WHOLE FILE
  156.     or in cases when is NEEDED to be sure that no other workstation can
  157.     jump in middle of counting values and change some of them just second
  158.     after they were counted. Function for file lock is FLOCK() and works
  159.     exactly the same way as RLOCK(), only effect is on COMPLETE file. After
  160.     FLOCK() issued is file still accessible for READING, but no-one can write
  161.     to any from file's records. All rlock() or flock() operation tried by
  162.     other workstation will be unsuccessful. Requirement for successful
  163.     flock() is therefore:
  164.  
  165.     -   no one has locked ANY from records in database
  166.     -   no one else has flocked() database
  167.  
  168.     General required are flock() or rlock() in functions/commands:
  169.  
  170.         rlock()                             flock()
  171.      ─────────────────────────────────   ────────────────────────────────────
  172.     :=                                  APPEND FROM
  173.     DELETE (for one record)             DELETE (for more records)
  174.     RECALL (for one record)             RECALL (for more records)
  175.     REPLACE (for one record)            REPLACE (for more records)
  176.     @..GET (operating on field)         UPDATE ON
  177.     fieldput()                          dbeval() (changing records)
  178.     fieldwblock()
  179.  
  180.     Considerably required is flock() in:
  181.  
  182.         SUM                             COPY TO         LIST
  183.         AVERAGE                         JOIN            DISPLAY
  184.         TOTAL                           LABEL
  185.         dbeval() (counting values)      REPORT
  186.         LOCATE and CONTINUE             SORT
  187.  
  188.         Those commands DO NOT change values in database at all, but are
  189.         dependent FROM values in database. In some cases it's therefore
  190.         good to think if it's normal and good that someone else will be
  191.         able change values in database during some counting processes.
  192.  
  193.     Clipper is placing OWN method of record locking on file which is NOT\
  194.     compatible with methods used by dBASE, FOXBASE, "C" language or others.
  195.     in general is this method based on locking one byte areas beyond any
  196.     possible end of file. This method is picked up because of needed side
  197.     effect, records are still READABLE even when lock is placed on them.
  198.     In normal case, when record is locked by locking AREA of file in which
  199.     record is, any locked area UNREADABLE on the same way as no-one can
  200.     WRITE to them. Clipper record which is LOCKED _must_ be readable from
  201.     other workstations, therefore locking is done by simulation of fake
  202.     records beyond possible end of file. All of this has next bad side
  203.     effect - any other software which wants to access Clipper files at the
  204.     same time as Clipper will have to follow exactly the same method of
  205.     record locking, otherwise it can only make big mess from Clipper database
  206.     files.
  207.  
  208. ┌╖  Several database operations are requiring EXCLUSIVE use of file and
  209. ╘╝  without this they will not operate at all.
  210.  
  211.     EXCLUSIVE use of database is giving application right to do ANYTHING
  212.     application wants with database. It's therefore required for some
  213.     Clipper operation. EXCLUSIVEly used database is not allowed even to
  214.     open from other workstations. From this point of view is power of
  215.     "locking" in this order:
  216.  
  217.         EXCLUSIVE used      no one else can ACCESS database file, database
  218.                             MAY NOT be open by other workstations, otherwise
  219.                             is impossible to make USE...EXCLUSIVE
  220.  
  221.         flock()             no one can CHANGE thing in database, rlock() or
  222.                             flock() from other workstations will fail, no one
  223.                             can EXCLUSIVE USE database
  224.  
  225.         rlock()             no one can CHANGE record in database, rlock() or
  226.                             flock() from other workstations will fail, no one
  227.                             can EXCLUSIVE USE database
  228.  
  229.         SHARED used         everyone can open database, use flock() or
  230.                             rlock(), but no can EXCLUSIVE open database
  231.  
  232.     Functions and commands for which EXCLUSIVE is required are:
  233.  
  234.         INDEX (*)                   PACK
  235.         REINDEX                     ZAP
  236.         dbcreateind() (*)           dbreindex()
  237.  
  238.     INDEX/dbcreateind() are partially excluded from this list in case that
  239.     on one is interested in multi-use of created indexes. INDEX/dbcreateind()
  240.     are generating index files which are not available for other workstations
  241.     by default, therefore EXCLUSIVE use of database is NOT required. But
  242.     there is one important detail:
  243.  
  244.     Index file generated on non-exclusive (or non-flocked()) database is
  245.     quite unstable in case someone just changed some values of keys in
  246.     middle of creating index key, therefore as general requirements can
  247.     be given:
  248.  
  249.      │║ Database _must_ be either file-locked or EXCLUSIVE used for
  250.      │║ case of index generation. Only with this one can overcome possible
  251.      │║ index destruction with later IE1210 (well know to most of us).
  252.  
  253. ┌╖  Appending of new record is not requiring rlock(), but it's requiring
  254. ╘╝  test of success.
  255.  
  256.     APPEND/dbappend() are used for ADDING ONE new record at END of database.
  257.     INSERT command which is present for example in FoxBase doesn't exist
  258.     in Clipper and therefore problem with new records is eliminated only to
  259.     appending at END of database.
  260.  
  261.     APPEND/dbappend() is by default trying to make one NEW record and then
  262.     place rlock() at this record. If something fails (two workstations
  263.     are doing dbappend() at the same time) dbappend() will not succeed and
  264.     NETERR() will be again returning information about error. Good sequence
  265.     therefore is:
  266.  
  267.         dbappend()
  268.         while neterr()
  269.             dbappend()
  270.         enddo
  271.  
  272.     This sample of course is limited in never ending waiting for append
  273.     of record, but what was told about flock() can be applied also in
  274.     custom appending function. There are therefore few points about
  275.     appending:
  276.  
  277.     -   record is ALWAYS locked if dbappend()/APPEND _was_ successful,
  278.         no need for additional RLOCK(), it's wasting of time
  279.     -   record is EMPTY after APPEND and MUST NOT be currently updated
  280.         in database YET nor in index files
  281.  
  282.     There is no need for checking success of APPEND/dbappend() in cases
  283.     of USE...EXCLUSIVE or flocked() databases, but considerable is fact
  284.     that flock() active _before_ dbappend() is replaced with rlock()
  285.     active _after_ dbappend() (see following comments).
  286.  
  287. ┌╖  Clipper is limited in number of rlock()/flock() on ONE per DATABASE
  288. ╘╝  and per WORKSTATION (program).
  289.  
  290.     Limitation of Clipper is that there can be ONLY ONE rlock() or flock()
  291.     per ONE database and workstation. One program can therefore place just
  292.     one lock per one open file. It's somehow limitation for many
  293.     applications, therefore many add-ons for Clipper are offering multiple
  294.     locks per file (DBFSIX, NETLIB for example).
  295.  
  296.     Also important point is that ANY RLOCK() or FLOCK() is removing
  297.     previously placed RLOCK() or FLOCK() in the same file, therefore
  298.     programmer MUST be careful when placing locks in the same file.
  299.  
  300. ┌╖  EVERY rlock() or flock() should have own dbunlock() or dbunlockall()
  301. ╘╝  function to assure proper unlocking and proper updating of data
  302.  
  303.     From moment of placing rlock() at record is very important to remember
  304.     that ANY changes made to this record MUST NOT be visible for other
  305.     workstations, even they have READ access to this record. They can see
  306.     still OLD values and old KEY values in index! dbunlock() is only one
  307.     which is REQUIRED to make changes visible. If this is not true in your
  308.     network, then believe or not - your network or your DOS version has
  309.     VERY important BUG, don't blame Clipper.
  310.  
  311.     On the same way as WHILE has proper ENDDO, IF has proper ENDIF, CASE
  312.     proper ENDCASE it's very important to have for every RLOCK() proper
  313.     DBUNLOCK(). There is of course possible to use DBUNLOCKALL(), but that's
  314.     solution not very clean - in some cases it can unlock something that
  315.     should stay YET locked.
  316.  
  317.     Thinking that NEXT rlock() (or flock()) will make dbunlock()
  318.     automatically is of course right, but it has one side effect, one can
  319.     miss easy proper lock-unlock combination in case of longer source files
  320.     with more actions between flock() and later flock() again. It's of course
  321.     easy to use it in way:
  322.  
  323.         while !oef()
  324.             if rlock()
  325.                 ADRES->CITY := upper(ADRES->CITY)
  326.             endif
  327.             dbskip(1)
  328.         enddo
  329.         dbunlock()
  330.  
  331.     This sample is CLEAR on FIRST SIGHT, therefore nothing against this way
  332.     of coding program, but in case that this source will become FEW pages
  333.     of lines, it's much better use dbunlock() on right place. Time saving
  334.     given by again and again using dbunlock() separately from rlock() are
  335.     not very important because rlock() in above example will have to make
  336.     unlock() of previous record anyway (with subsequent update actions).
  337.  
  338. ┌╖  Using of dbcommit()/COMMIT can be sometime too much
  339. ╘╝
  340.     dbcommit()/COMMIT/dbcommitall() are in most cases very powerful.
  341.  
  342.     In processing od DATABASE files of Clipper are several levels of
  343.     buffering (CACHING). First there is Clipper internal buffering of data
  344.     in EMS or conventional memory (if available) which buffers complete
  345.     records of database when possible, then there is DOS buffering (and
  346.     Caching) which works between disk hardware and Clipper requests. It
  347.     uses either buffers created by CONFIG.SYS command BUFFERS= or cache
  348.     buffers created by CACHE software (SMARTDRV.SYS in standard). In
  349.     network environment there is in some cases network buffering at
  350.     workstation which is NOT active for Clipper files opened as SHAREABLE
  351.     and which IS active for EXCLUSIVE open files. COMMIT/dbcommit()
  352.     possibility of CLipper is related to those buffers:
  353.  
  354.     -   DOS buffers are flushed TO DISK in versions 3.3+
  355.     -   CLIPPER buffers are flushed TO DOS in versions under 3.3
  356.     -   SERVER buffers are flushed to SERVER disk in Netware 3.11 with
  357.         NetWare Shell of versions 3.22+
  358.  
  359.     It's generally known and approved that dbunlock() is far enough to
  360.     make visible record changes in all normal cases. Committing data is
  361.     in most cases even not very good idea because it can make additional
  362.     unwanted traffic inside of server between server CACHE memory and
  363.     physical disk.
  364.  
  365.     Warning anyway, there ARE revisions of DOS which are affecting file
  366.     handling functions and which HAVE significant problems with file and
  367.     record related function (not even locking) when running under Networks.
  368.     One sample can be TANDON DOS version 3.3 which is exception from case
  369.     that dbunlock() is enough for making updates visible, dbcommit() IS
  370.     required in this case to SEE dbunlock() activated.
  371.  
  372. ┌╖  DOS based networks are REQUIRING use of SHARE.EXE
  373. ╘╝
  374.     Rule about DOS based network is that ANYTHING that is coming to be
  375.     SERVER and will have to share files for other workstation MUST have
  376.     loaded SHARE.EXE program BEFORE any other network programs OR in
  377.     some SPECIAL order when it's specified by documentation for network.
  378.  
  379.     What is coming to be problem is that SHARE.EXE by default is ready
  380.     only for SINGLE user machine with limited number of files opened.
  381.     MultiUser SHARE.EXE requires some changes in parameters. SHARE.EXE
  382.     has TWO parameters and common knowledge of them is not very good.
  383.  
  384.     /F:n is used to specifying SIZE OF FILE NAME POOL which SHARE.EXE will 
  385.     allocate. Standard size of this pool is only 2048 bytes and therefore 
  386.     very small. ONE opened file from server will in general require about 
  387.     20bytes for name + 20 bytes (exactly 11bytes of information and full size 
  388.     of path+name) for informations, and that means that 2048 is space for 50 
  389.     files. Common Clipper programs are easily opening this number of files 
  390.     PER PROGRAM.  Therefore take number of workstation accessing your server, 
  391.     count let say 60 files to open from every workstation and result will be 
  392.     <n>*60*40. Be careful in thinking, because MEMORY WILL BE ALLOCATED from 
  393.     CONVENTIONAL memory of server (in most cases) and therefore CAN limit 
  394.     significantly any other operations.
  395.  
  396.     /L:n is used for specifying SIZE OF LOCK POOL which SHARE.EXE will
  397.     allocate. Standard size of this POOL is allowing 20 locks. That's also 
  398.     not good enough because Clipper program CAN make the same number of
  399.     locks as is number of files it's opening. Therefore get number of 
  400.     workstations multiplied by number of files (<n>*60 in sample case) and
  401.     that's /L:n which should be used. This parameter is NOT increasing
  402.     memory usage so much, therefore don't worry about it.
  403.  
  404. ┌╖  DOS based network are requiring .EXE and .OVL files marked as READ ONLY
  405. ╘╝
  406.     DOS based network (and may be that some others also) are requiring that
  407.     .EXE and .OVL files from Clipper program will be marked as READ ONLY to 
  408.     allow more than one workstation run the same file at the same time. It's 
  409.     problem of DOS default method of opening non-Read-only file which is 
  410.     making impossible to open it twice by default. Therefore just don't 
  411.     forget to mark them with ATTRIB as +R.
  412.  
  413. ┌╖  WORKSTATION is NOT requiring SHARE.EXE
  414. ╘╝
  415.     ANY workstation running in ANY network doesn't need SHARE.EXE, don't
  416.     worry about clever recommendations to load SHARE.EXE on all workstations 
  417.     of your network. It's wrong. It will only take up your memory (which is
  418.     critical in many cases) and will do nothing, or worse will conflict with
  419.     your programs and make problems. 
  420.  
  421.     From this rule is only ONE exception. Microsoft DOS 4.01 running 
  422.     workstations with HARD DISK bigger than 32MB _are_ _requiring_ SHARE.EXE 
  423.     to be loaded. IF it's not loaded computer will run smoothly until disk is 
  424.     started to be allocated in area over 32MB and some stupid program using 
  425.     old way of file handling (like SideKick for example) will be started. 
  426.     After it harddisk of workstation is overwritten...
  427.  
  428. ┌┐  Computers or workstations running MULTIUSER software and planning 
  429. └┘  running multiple Clipper programs over the same data NEED SHARE.EXE
  430.  
  431.     Anything running DesqView, MultiDos, MS Windows or anything else which is 
  432.     providing multi tasking capabilities should load SHARE.EXE before start
  433.     of multiuser software otherwise lower copy of DOS will not be able to 
  434.     handle file/record locking and shared accessing. In general multi task 
  435.     environment SHOULD BE TAKEN AS EQUAL TO SIMPLE NETWORK, therefore 
  436.     anything written before or after this statement can be active...
  437.  
  438. ┌╖  Novell Netware SHAREABLE flag is DANGEROUS, DO NOT try mark your files
  439. ╘╝  as SHAREABLE (FLAG +S)
  440.  
  441.     SHAREABLE flag of Novell Netware files is something that MUST be avoided 
  442.     to use for Clipper data files. SHAREABLE flag has for Novell Server only 
  443.     one meaning that it should ignore any file/record locking on given file 
  444.     because applications using file will maintain OWN method of locking and 
  445.     checking. As far as CLipper is still using standard method of locking, 
  446.     only far beyond end of file it means that any locks can went well wrong 
  447.     when file is marked Shareable. Please try understand this statement as 
  448.     copied out from official Novell statement which can be made available and 
  449.     therefore please understand this as end of myth of Shareable attribute.
  450.  
  451.     There is no reason to mark Clipper database file on any special way in
  452.     any known network, especially not in Novell Netware.
  453.  
  454. ┌╖  Be sure that Clipper application users have enough rights in directories
  455. ╘╝  where CLipper program will be working.
  456.  
  457.     Often problem is that there is not enough rights for Clipper .EXE file to
  458.     run and to access his data. In Clipper it's not very difficult, just give 
  459.     ALL rights in directory where .EXE is running, in TEMPorary directory and
  460.     in all directories where database related files are located. I didn't yet
  461.     made experiments with giving less rights, but generally it shouldn't be
  462.     a problem because CLipper application will need anyway separate direc-
  463.     tories for program and data and giving rights in secured network will not
  464.     be very big problem.
  465.  
  466.     There is also little bug in OLDER versions of Netware. FILES in Netware
  467.     are ALWAYS created WITH OWNER. It's good idea to create ALL files AS
  468.     SUPERVISOR because this one will NEVER be deleted. IF is installed 
  469.     limiting of space by users it can be that file create by let say user
  470.     named FRED will give strange errors for one simple reason. User FRED
  471.     is already deleted from server and therefore space available checking
  472.     mechanism is unable to determine if it can append new records to file
  473.     and will give "Disk Full" messages even when there are MEGABYTES of
  474.     free space. Just change owner of files to SUPERVISOR or somebody who
  475.     is existing in network and problem will be solved.
  476.  
  477. ┌╖  Don't forget for TEMP drives!
  478. ╘╝
  479.     TEMP drive specified for application in SET CLIPPER can be source of
  480.     problems when someone will forget to create this directory or don't give 
  481.     rights for users in this directory. Clipper application WILL create 
  482.     sooner or later some swap and temporary files in there and if it will be
  483.     unable to locate directory? It will just jump out of program without 
  484.     possibility to catch this error!
  485.  
  486.     It's GOOD idea to collect ALL temporary files in separate directory 
  487.     called for example TEMP (or $TEMP$) because they are garbage in meaning
  488.     of network. If workstation HAS harddisk or RAMDISK is good to redirect
  489.     those temporary files on them. It can save LOT of megabytes transferred 
  490.     through network and also therefore can speed up your application.
  491.     
  492. ┌╖  What about marking some directories as PURGE in 3.11 Netware 
  493. ╘╝
  494.     Since Novell Netware 3.11 is Novell server SAVING _all_ deleted files
  495.     for undeletion. What it means is usage of disk space on server (he will 
  496.     purge them automatically when needed) and also time required for those 
  497.     and later for PURGE operation. It's nice to be able undelete by accident 
  498.     deleted file two weeks ago, but in some cases it's good to use PURGE flag 
  499.     for directories (command is FLAGDIR <dir_name> P). Directories marked 
  500.     with this Purge flag will not try to keep files and all deleted will be 
  501.     automatically immediately purge. Good candidate for FLAGDIR P command is 
  502.     TEMP directory in ALL cases, otherwise Novell Netware server will have 
  503.     after week of working with your Clipper program thousands of files stored 
  504.     in salvageable state and for nothing.
  505.  
  506. ┌╖  Quest for file handles
  507. ╘╝
  508.     Coming into troubles with file handles is very easy. General rules will 
  509.     be described just step by step to help cover this kind of problems.
  510.  
  511.     First of all, Clipper is VERY hungry for file handles (all other xBase
  512.     derivates are anyway also because of using the same technique of file
  513.     management), one therefore must be able calculate needs of his own 
  514.     program for file handles:
  515.  
  516.     -   one file handle for .EXE file                   *ALWAYS*
  517.     -   one file handle for every .OBL file             *WHEN USED*
  518.     -   two file handles for swapping files             *ALWAYS*
  519.         this can be even more when one allows more,
  520.         SET CLIPPER=DYNF:<n> is used for this
  521.     -   one file handle per .DBF file                   *ALWAYS*
  522.     -   one file handle per .DBT .FPT file              *WHEN USED*
  523.     -   one file handle per every .NTX .IDX .NDX        *WHEN USED*
  524.     -   one file handle per every .CDX                  *WHEN USED*
  525.     -   one file handle per every fopen(), fcreate(),
  526.         report, label, set alternate, set print to,
  527.         set device to, append from, copy to, copy file,
  528.         copy structure, create, create from, save, 
  529.         restore, sort, type, update                     *WHEN USED*
  530.     -   one or more handles when CLD.EXE or CLD.LIB     *WHEN USED*
  531.         is used (.PRG is open at least).
  532.  
  533.     Most file hungry moment from all those is fact of .DBF needs another file 
  534.     handle for any memo fields (.DBT file) and then for EVERY index related 
  535.     to one .DBF is required additional file handle for .NTX (or .IDX or .NDX) 
  536.     file. It's most limiting issue in using file handles and it can be solved 
  537.     only by two ways - one is requiring structural changes of applications, 
  538.     second one using of SIX RDD which allows using of .CDX file which can 
  539.     include ALL (and even more) .NTX in one file handle... (our main 
  540.     application which is user part of FAX/TELEX/MAIL program was using 45 
  541.     file handles with DBFNTX driver, now it's using 26 file handles with 
  542.     DBFSIX driver).
  543.  
  544.     After counting this "BIG" number of files which application is using is 
  545.     good to write this number down and start setting up system to allow use 
  546.     of them.
  547.  
  548.     First place where one meets FILE HANDLEs specification is CONFIG.SYS,
  549.     command FILES=<n> is giving maximum number of file handles which may be 
  550.     used in computer (workstation) and is by default ONLY 20, therefore for 
  551.     Clipper needs to be a bit more. Every file handle from FILES= will of 
  552.     course grab additional memory, therefore is not good to try allocate TOO 
  553.     much of them. But for sure it MUST be _more_ than "BIG" number from 
  554.     Clipper application. In general "BIG"+5 is good for <n>, but it's true 
  555.     for standard MS DOS without TSR programs (Norton Guide engine NG.EXE is 
  556.     for example using one file handle for NG.INI file!). 4DOS replacement of 
  557.     COMMAND.COM can keep open additional file handles for swapping files, 
  558.     therefore "BIG" and <n> should be more far from each other or "BIG" 
  559.     should be bigger than real application need.
  560.  
  561.     One thing is for sure anyway, LOCAL running application WILL NEVER be 
  562.     able open more than <n> files (allocated in CONFIG.SYS).
  563.  
  564.     Little warning, QEMM has nice utility called FILES.COM which CAN create 
  565.     additional file handles in High Memory and save conventional memory for 
  566.     application. In this case is FILES=8 most sufficient in CONFIG.SYS and 
  567.     later FILES <n>-8 in AUTOEXEC.BAT will do additional allocation of 
  568.     required. But warning, FILES utility from QEMM is _not_ compatible with 
  569.     file handles used in DR DOS 6.0 and even if it will not complain it will 
  570.     NOT give required file handles and Clipper application will be magically 
  571.     refusing to work even if all looks fine.
  572.  
  573.     SECOND place where is requirement to specify file handles in command 
  574.     line for your .EXE (or in SET CLIPPER or in linker burn-in script). 
  575.     Clipper written application is using Microsoft like run engine which by 
  576.     default is getting only 20 file handles from DOS under. Call for DOS 
  577.     service to getting additional file handles is required for opening more 
  578.     than 20 of them. Clipper is not so clever to just call at beginning for 
  579.     maximum (255) and is requiring programmer (user) to give request for this 
  580.     number. SET CLIPPER=F<x> or //F<x> for .EXE run is therefore REQUIRED to 
  581.     get more than 20 file handles available. 
  582.  
  583.     GOOD TIP. If your linker is allowing burn-in of Clipper environment, just
  584.     burn in F255 and forget about this nasty and stupid parameter. It will 
  585.     not give any harm or extra memory used (yes, ONE byte per file handle 
  586.     rounded to 16bytes boundary which is harmless in Clipper memory usage) 
  587.     and no longer thinking about which F<x> parameter is active now.
  588.  
  589.     Until now we were talking about SINGLE user/task environment on single
  590.     PC. Different situation is coming in network and that's what we should
  591.     discuss especially.
  592.  
  593.     Novell Netware is most often used network, therefore we can start there.
  594.  
  595.     First, Novell Netware 2.x servers are GENERATED with FIXED number of
  596.     available file handles and MAXIMUM possible is only 1000 (that's 
  597.     sufficient for 16 workstations opening 60 files for example!). Because
  598.     using of more available file handles on servers requires more memory in
  599.     server some technicians generating 2.x servers were afraid of putting 
  600.     more MB of memory and generated servers with 200 handles available (for 
  601.     example). That's something that can break your plans to run application 
  602.     from CLipper in give server immediately. Therefore make always check
  603.     for how much of files is server generated. Ask supervisor of network for 
  604.     look into SYSCON utility, Statistics submenu and General statistics. All 
  605.     number are there, even number talking about current and peak number of 
  606.     opened files. From those three numbers is possible start thinking about 
  607.     ability to run Clipper program. Example:
  608.  
  609.             Maximum     Peak        Current
  610.                 600         560         320
  611.  
  612.         This will be not very good place for running CLipper program, unless 
  613.         this program will be the one running at most workstations at the same 
  614.         time which will slow down normal workload of files. 560 in peak is 
  615.         VERY near of configured MAXIMUM and that's a sign of need to change 
  616.         maximum value.
  617.  
  618.     Problem. Novell 2.x server is GENERATED from about 30 floppies and then 
  619.     LOADED into harddisk by special loader, ANY changes of parameters of 
  620.     server's operating system are requiring NEW generation based on OLD 
  621.     definitions. In most cases 2.x server is impossible to generate again 
  622.     because original supporter has not floppies anymore or doesn't exist.
  623.  
  624.     Novell Netware 3.11 server is NOT limited in number of files for opening 
  625.     in generation or maximum given by exact number. Only available memory of 
  626.     server is limitation of number of files to open (and speed of course), 
  627.     therefore if your application is going to be running on 3.11 Network and 
  628.     server, no problem at all.
  629.  
  630.     Every workstations in Novell Netware network will have available 40 file 
  631.     handles by default WITHOUT giving any specification. If there is 
  632.     requirement for more it's needed to place request for it in NET.CFG (or 
  633.     SHELL.CFG) file. SHELL.CFG is _old_ used name which is replaced by 
  634.     NET.CFG in last days. Command to place in there is FILE HANDLES=<m> and 
  635.     it will assure ability to open maximum of <m> files FROM NETWORK.
  636.  
  637.     IMPORTANT NOTE. Files allocated in CONFIG.SYS by FILES=<n> and files 
  638.     allocated from network by FILE HANDLES=<m> are INDEPENDENT from each 
  639.     other. <n>+<m> MAY NOT exceed 254 and in old versions of Netware Shell 
  640.     (NETX) it will NOT give any warning when this is happening and will 
  641.     allocate just default (40 or even less). New netware Shell is giving 
  642.     warning and refusing to load when <n>+<m> is over 254.
  643.  
  644.     <n>+<m> is also NUMBER OF FILES AVAILABLE for OPEN _AT_ workstation,
  645.     but <n> is talking about LOCAL FILES and <m> about NETWORK FILES (files 
  646.     from network). This fact can also affect CLipper application with F<x> 
  647.     setting by the way (that's why F255 is most nice solution also). From 
  648.     this comment is also coming out one other warning, NUL device which is 
  649.     using file handle when opened more times is using ALWAYS local file 
  650.     handle and not Netware file handle when used for testing number of file 
  651.     handles available for opening.
  652.  
  653.     Non-Netware networks can have similar limitations of files available to 
  654.     open in server. Maybe someone else is able to elaborate on this for Lan 
  655.     Manager networks, but we do not support them nor use them (for enormous 
  656.     slowness) and it's hard to say.
  657.  
  658.     DOS based network servers are using different ways of overcoming problem 
  659.     that MS DOS allows maximum of 255 file handles (file handle is 8bit 
  660.     number only) and therefore is ALWAYS matter of configuration of server 
  661.     HOW much of files it will allow to open simultaneously. Some from DOS 
  662.     based networks are even limited to 255 files maximum (old versions of 
  663.     Lantastic were for example) or have significant difficulties when trying 
  664.     to successfully and reliable work with more than 255 files. Always check 
  665.     with network supervisor for setting and count them in Clipper application 
  666.     installation.
  667.  
  668. ┌╖  Versions of network support software or network operating systems
  669. ╘╝
  670.     There was already article devoted to Novell Netware 3.11 patches and 
  671.     their importance in correct working network and also article about 
  672.     Netware Shell releases and their troubles. Both are available in 
  673.     Clipper BBS Magazine number 14 and are also uploaded to Compuserve's
  674.     forum CLIPPER and DBADVISOR as text files free to download.
  675.  
  676.     In general, IF application is not running properly be sure to take a look 
  677.     and check if networking software is latest version or it's patched with 
  678.     latest available patches. In world doesn't exist software WITHOUT bugs 
  679.     and shortcuts and therefore patches are something very usual in serious 
  680.     companies (NANTUCKET was exception because waiting for 5.01 patch of 
  681.     CLipper 5.0x was very, very long). Example can be taken on Novell Netware 
  682.     3.11 operating system which has few very important bugs related 
  683.     immediately with Clipper (and any other database applications) which can 
  684.     lead in major problems. On the same way it's VERY important to use latest 
  685.     Shell programs (Shell programs are those who allow workstation to access 
  686.     network files and services - those like IPX/NETX or ODI/NETX in Novell 
  687.     Netware, NET in Lantastic and so on) are of latest versions also. MANY 
  688.     from problems are related to old version of Shell program which has well 
  689.     known and already fixed bugs. In Novell Netware it's matter of having 
  690.     just latest 3.26 version of NETX because before this one is one important 
  691.     problem related to VISIBILITY of updates in network...
  692.  
  693. ┌╖  Memory problems
  694. ╘╝
  695.     We all know that CLipper is very tight with memory usage. RTLINKed 
  696.     application is maybe better to not describe so much because standard 
  697.     RTLINK distributed with Clipper is not very good in handling big programs 
  698.     with C, ASM and CLIPPER combination. Fortunately we do have our BLINKERs, 
  699.     WARPLINKs which are better in memory handling, but still it's not 
  700.     optimal and it's caused by Clipper philosophy.
  701.  
  702.     Clipper us using VERY large runtime engine which is present in every .EXE 
  703.     created even if it's one line program. It makes some base of memory usage 
  704.     which CANNOT be reduced very much. All additional CLipper code and other 
  705.     libraries are sooner or later coming to create monstrous applications with 
  706.     .EXE file over 1MB in size and load sizes over 350KB (load size is size 
  707.     reported by linker when finished work on bunch of .OBJ and .LIB files). 
  708.     Those monstrous programs are requiring about 350KB of just memory loaded 
  709.     with programs and at least another 100KB of memory used for program to 
  710.     have it running. It comes in 450KB of memory needed for POSSIBILITY to 
  711.     run program. That's not so big problem in SINGLE user computer because 
  712.     typical free memory in there can be some 550KB in older DOS versions and 
  713.     some 600KB in DOS 5.0 with DOS loaded HIGH. Where problem is coming is 
  714.     network because Shell drivers are requiring some memory for work also. 
  715.     Free memory for Clipper program then can end in between 50KB till 90KB 
  716.     less than in non-network case. And that can become critical in monstrous 
  717.     megabyte applications. 
  718.  
  719.     This part of our long article will therefore try to give little light and 
  720.     magic into memory issue. Don't expect too much, it's just list of 
  721.     practical experiences from own life.
  722.  
  723.     -   reduce size and load size of Clipper application
  724.  
  725.       ■ Do not use PLL for living versions of your applications. It's saving 
  726.         of course size on your disk but .PLL is requiring some additional
  727.         impact on load and run size of application
  728.  
  729.       ■ Do not use incremental linked application in living environment. 
  730.         Sounds silly, but that's often happening that application linked with 
  731.         INCREMENTAL ON (we are NOT talking about RTLINK where incremental 
  732.         link is now working at all) is by mistake used. Incremental linking 
  733.         is making .EXE file bigger by padding all functions by additional 
  734.         empty space for later replacing relink. It requires therefore more 
  735.         memory for running of program (much more).
  736.  
  737.       ■ Do not use application linked with debugger or debugging code for 
  738.         living environment. /B switch of CLIPPER.EXE will generate object 
  739.         file which will force linkers to make .EXE file which is bigger and 
  740.          also requires more memory. Be sure that NO ONE from .OBJ files in 
  741.         your link script (or in your libraries) is compiled with /B because 
  742.         it's enough to have one to have included all debug informations. It's 
  743.         good (and needed for testing), but unwanted for living environment.
  744.  
  745.       ■ Reduce size of your .OBJ code by excluding line number informations 
  746.         for living environment. /L switch of CLIPPER.EXE is required for 
  747.         doing so. Side effect of this is of course that all ERROR reports 
  748.         will have line number ZERO, but living application shouldn't produce 
  749.         so much errors anyway. Line number is TWO BYTES in .OBJ for EVERY 
  750.         line of your SOURCE included in source and that can mean significant 
  751.         saving of space!
  752.  
  753.       ■ In debugging cycle link CLD.LIB into your application instead of 
  754.         using separated CLD.EXE. Save of memory is NOT SO BIG, but can make 
  755.         significant difference in ability of debugging own code. Don't forget 
  756.         in this case that CLD.LIB _must_ be included in linking script as 
  757.         FILE CLD.LIB and not as SEARCH CLD (or ALLOCATE CLD, LIB CLD) because 
  758.         it's nice present from Nantucket. But then, DO NOT forget to REMOVE 
  759.         CLD.LIB from link script for living environment application, 
  760.         otherwise anyway inactive CLD.LIB will take additional memory.
  761.  
  762.       ■ Don't think that just specifying list of libraries and object modules 
  763.         for your linker will take care of proper and optimal overlaying. Most 
  764.         from libraries are combination of CLipper and C/ASM code and should 
  765.         be overlaid explicitly by specification. Most from CLIPPER.LIB can be 
  766.         also forced to overlay and all this can save lot of memory. Don't 
  767.         forget in this case of course that invoking static overlay manager 
  768.         will require some additional memory (RTLINK about 18KB) and therefore 
  769.         effect from overlaid code must be bigger than impact of overlay 
  770.         manager present in .EXE code. Some examples of scripts for BLINKER 
  771.         1.51 are here:
  772.  
  773.         TELEPATHY - communication library
  774.         ┌───────────────────────────────────────────────┐
  775.         │   search TPROOT                               │
  776.         │   BEGINAREA                                   │
  777.         │       allocate TPOVL                          │
  778.         │   ENDAREA                                     │
  779.         └───────────────────────────────────────────────┘
  780.  
  781.         NOVLIB - Novell Netware library
  782.         ┌───────────────────────────────────────────────┐
  783.         │   BEGINAREA                                   │
  784.         │       allocate NLEXTEND, NLMAIN               │
  785.         │   ENDAREA                                     │
  786.         └───────────────────────────────────────────────┘
  787.  
  788.         EXTEND - Part of Clipper libraries
  789.         ┌───────────────────────────────────────────────┐
  790.         │   BEGINAREA                                   │
  791.         │       ALLOC extend                            │
  792.         │   ENDAREA                                     │
  793.         └───────────────────────────────────────────────┘
  794.  
  795.         CLIPPER - Main Clipper library
  796.         ┌─────────────────────────────────────────────────────────────────┐
  797.         │   SEARCH CLIPPER                                                │
  798.         │   # tbrowse are forced in ROOT otherwise it's too slow          │
  799.         │   MOD tbrowse0, tbrowse1, linelen                               │
  800.         │                                                                 │
  801.         │   # needed for NETLIB library                                   │
  802.         │   MOD txopen, eve, filesys                                      │
  803.         │   # those marked with ## is possible to overlay too but         │
  804.         │   # main issue can be slowness of system in some cases          │
  805.         │   BEGINAREA                                                     │
  806.         │       MOD accept, acopy, adel                                   │
  807.         │   ##  MOD aeval                                                 │
  808.         │       MOD ains, appinit, atail                                  │
  809.         │   ##  MOD box , color                                           │
  810.         │       MOD cmem                                                  │
  811.         │   ##  MOD date                                                  │
  812.         │       MOD dbcmd0, dbcmd1, dbcmd2, dbcmd3, dbcmd4, dbcmd5        │
  813.         │       MOD dbcreate                                              │
  814.         │   ##  MOD dbf0, dbf1, dbfdyn                                    │
  815.         │       MOD dbjunct, dbnubs, dbstruct, delimdyn, dlm0, dlm1       │
  816.         │   ##  MOD dtx0, dtx1, dtxdyn                                    │
  817.         │       MOD diskio , dynina                                       │
  818.         │   ##  MOD errorsys                                              │
  819.         │       MOD errsys0, errsys1                                      │
  820.         │   ##  MOD event, extend, fget, field                            │
  821.         │       MOD getenv, gets0, gets1, gets2, gx, joinlist, lupdate    │
  822.         │   ##  MOD maxrow                                                │
  823.         │       MOD memory, mrelease, msave, net, nmsghdr                 │
  824.         │       MOD oldbox, oldclear, philes, run, saverest, scroll       │
  825.         │       MOD sdf0, sdf1, sdfdyn, send, seq                         │
  826.         │   ##  MOD set, setcurs, sortbloc                                │
  827.         │       MOD sortof, squawk, startsym                              │
  828.         │   ##  MOD symsys                                                │
  829.         │       MOD tb                                                    │
  830.         │   ##  MOD txopen      ##  NETLIB needs it in root               │
  831.         │       MOD vall                                                  │
  832.         │   ##  MOD vblock, vdb                                           │
  833.         │       MOD vdbg, version                                         │
  834.         │   ##  MOD vmacro, vnone, vops, vpict, vterm, workarea, wrt2err  │
  835.         │       MOD xmacro                                                │
  836.         │                                                                 │
  837.         │       MOD _afields, _appini, _atpromp, _century                 │
  838.         │       MOD _dbcopy, _dbdelim, _dbflist, _dbghelp                 │
  839.         │       MOD _dbginsp, _dbgmenu, _dbjoin, _dblist                  │
  840.         │       MOD _dblocat, _dbsdf, _dbsort, _dbstrux                   │
  841.         │       MOD _dbtotal, _dbupdat, _fledit                           │
  842.         │   ##  MOD _getmsg, _getsys                                      │
  843.         │       MOD _helpkey, _input, _readvar,                           │
  844.         │   ##  MOD _savescr, _setfunc                                    │
  845.         │       MOD _setta, _text, _wait                                  │
  846.         │                                                                 │
  847.         │       MOD memoedit, memotrain, memoread, memowrit               │
  848.         │       MOD memoline, mlcount, mlpos                              │
  849.         │                                                                 │
  850.         │       MOD is, examplec, hardcr, directry, copyfile              │
  851.         │       MOD typefile, diskspac, achoice, osdate                   │
  852.         │       MOD examplea, initexit, strtran                           │
  853.         │                                                                 │
  854.         │   ENDAREA                                                       │
  855.         │                                                                 │
  856.         │   SEARCH terminal                                               │
  857.         │   # i do not use DBFNTX anymore, therefore i removed it out     │
  858.         │   # SEARCH dbfntx                                               │
  859.         └─────────────────────────────────────────────────────────────────┘
  860.  
  861.         DBFSIX - RDD replacement of DBFNTX
  862.         ┌─────────────────────────────────────────────────────────────────┐
  863.         │   FILE DBFSIX.OBJ                                               │
  864.         │   #FILE DBT.OBJ                                                 │
  865.         │   FILE DBCREATE.OBJ                                             │
  866.         │                                                                 │
  867.         │   # Speeds up index creations when marked out                   │
  868.         │   #MODULE SXCREATE                                              │
  869.         │   # using standard overlay link from Successware                │
  870.         │   @\dbfsix\dbfsix.lnk                                           │
  871.         │                                                                 │
  872.         │   BEGINAREA                                                     │
  873.         │       ALLOCATE DBFSIX                                           │
  874.         │   ENDAREA                                                       │
  875.         └─────────────────────────────────────────────────────────────────┘
  876.  
  877.         NETLIB - Networkin library
  878.         ┌────────────────────────────────────────────────────────────────┐
  879.         │   MOD A0FIX, C1LOCK, A0BREAK                                   │
  880.         │                                                                │
  881.         │   BEGINAREA                                                    │
  882.         │       allocate NL150, HORIZ50                                  │
  883.         │   ENDAREA                                                      │
  884.         └────────────────────────────────────────────────────────────────┘
  885.  
  886.         Dr.Switch ASE - swapping and making program TST is ALL in ROOT
  887.         ┌───────────────────────────────────────────────────────────────┐
  888.         │   MODULE ASE                                                  │
  889.         │   SEARCH ASE                                                  │
  890.         └───────────────────────────────────────────────────────────────┘
  891.  
  892.         NANFORUM TOOLKIT - best public domain library
  893.         ┌───────────────────────────────────────────────────────────────┐
  894.         │   BEGINAREA                                                   │
  895.         │       ALLOC nanfor                                            │
  896.         │   ENDAREA                                                     │
  897.         └───────────────────────────────────────────────────────────────┘
  898.  
  899.         BLINKER general script for LIVING environment application
  900.         ┌───────────────────────────────────────────────────────────────┐
  901.         │   # use a fixed overlay area instead of the free pool         │
  902.         │   BLINKER OVERLAY FIXED                                       │
  903.         │   #                                                           │
  904.         │   # allocate 60K to the overlay pool                          │
  905.         │   BLINKER OVERLAY OPSIZE 60                                   │
  906.         │   #                                                           │
  907.         │   # full link only                                            │
  908.         │   BLINKER INCREMENTAL OFF                                     │
  909.         │   #                                                           │
  910.         │   # call stack size and fixes stack size                      │
  911.         │   BLINKER PROCEDURE DEPTH 55                                  │
  912.         │   STACK 5120                                                  │
  913.         │   #                                                           │
  914.         │   # overlay in EMS aare disable because of using EMS in others│
  915.         │   BLINKER OVERLAY PAGEFRAME OFF                               │
  916.         │   #                                                           │
  917.         │   # and use upper memory blocks for overlay pool to save memor│
  918.         │   BLINKER OVERLAY UMB ON                                      │
  919.         │   #                                                           │
  920.         │   # Burn in environment                                       │
  921.         │   BLINKER EXECUTABLE CLIPPER F255;CGACURS;SWAPPATH:'TEMP\'    │
  922.         │   #                                                           │
  923.         │   # allow users override environment with SET CLIPPER         │
  924.         │   BLINKER ENVIRONMENT OVERRIDE                                │
  925.         │   #                                                           │
  926.         │   # set different than SET BLINKER                            │
  927.         │   BLINKER ENVIRONMENT NAME APPSET                             │
  928.         │   #                                                           │
  929.         │   # don't delete .EXE file when error                         │
  930.         │   BLINKER EXECUTABLE NODELETE                                 │
  931.         │   #                                                           │
  932.         │   # burn-in serial numbers                                    │
  933.         │   BLINKER EXECUTABLE SERIAL (c)NETCONSULT 1992, (DD)          │
  934.         │   #                                                           │
  935.         │   # display list of all duplicates                            │
  936.         │   BLINKER MESSAGE DUPLICATES                                  │
  937.         │   #                                                           │
  938.         │   # don't blink, it's bothering me                            │
  939.         │   BLINKER MESSAGE NOBLINK                                     │
  940.         │   #                                                           │
  941.         │   # don't search for default libraries!                       │
  942.         │   NODEFLIB                                                    │ 
  943.         └───────────────────────────────────────────────────────────────┘
  944.  
  945.         BLINKER general script for TESTING of application
  946.         ┌───────────────────────────────────────────────────────────────┐
  947.         │   # uncomment this when needed listing on the screen          │
  948.         │   #VERBOSE                                                    │
  949.         │   #                                                           │
  950.         │   # uncomment this when needed debugging/profiling            │
  951.         │   #DEBUG                                                      │
  952.         │   #                                                           │
  953.         │   # uncomment this for creating a MAP file                    │
  954.         │   #MAP                                                        │
  955.         │   #                                                           │
  956.         │   # use a fixed overlay area instead of the free pool         │
  957.         │   BLINKER OVERLAY FIXED                                       │
  958.         │   #                                                           │
  959.         │   # allocate 60K to the overlay pool                          │
  960.         │   BLINKER OVERLAY OPSIZE 60                                   │
  961.         │   #                                                           │
  962.         │   # incremental link as standard                              │
  963.         │   BLINKER INCREMENTAL ON                                      │
  964.         │   #                                                           │
  965.         │   # call stack size and fixes stack size                      │
  966.         │   BLINKER PROCEDURE DEPTH 55                                  │
  967.         │   STACK 5120                                                  │
  968.         │   #                                                           │
  969.         │   # overlay in EMS aare disable because of using EMS in others│
  970.         │   BLINKER OVERLAY PAGEFRAME OFF                               │
  971.         │   #                                                           │
  972.         │   # and use upper memory blocks for overlay pool to save memor│
  973.         │   BLINKER OVERLAY UMB ON                                      │
  974.         │   #                                                           │
  975.         │   # Burn in environment                                       │
  976.         │   BLINKER EXECUTABLE CLIPPER F60;CGACURS;INFO                 │
  977.         │   #                                                           │
  978.         │   # allow users override environment with SET CLIPPER         │
  979.         │   BLINKER ENVIRONMENT OVERRIDE                                │
  980.         │   #                                                           │
  981.         │   # set different than SET BLINKER                            │
  982.         │   BLINKER ENVIRONMENT NAME APPSET                             │
  983.         │   #                                                           │
  984.         │   # don't delete .EXE file when error                         │
  985.         │   BLINKER EXECUTABLE NODELETE                                 │
  986.         │   #                                                           │
  987.         │   # burn-in serial numbers                                    │
  988.         │   BLINKER EXECUTABLE SERIAL (C) NETCONSULT 1992, (DD)ß        │
  989.         │   #                                                           │
  990.         │   # NO display list of all duplicates                         │
  991.         │   #BLINKER MESSAGE DUPLICATES                                 │
  992.         │   #                                                           │
  993.         │   # don't blink, it's bothering me                            │
  994.         │   BLINKER MESSAGE NOBLINK                                     │
  995.         │   #                                                           │
  996.         │   # don't search for default libraries!                       │
  997.         │   NODEFLIB                                                    │
  998.         └───────────────────────────────────────────────────────────────┘
  999.  
  1000.       ■ Using of Clipper code is better for memory than C/ASM written code in 
  1001.         cases when SPEED is not very important. Dynamic overlaying of Clipper 
  1002.         code in ALL cases is giving better memory usage with side effect on 
  1003.         speed of course. Most from C/ASM code is very fast, small but 
  1004.         overlaid in not so good way as Clipper. But all this is question of 
  1005.         used linker of course.
  1006.  
  1007.       ■ do not allocate unneeded variables, PRIVATE or PUBLIC variables. Make 
  1008.         variables which are really needed and do them as LOCAL or STATIC. All 
  1009.         others can have impact on memory when used. It's saving of bytes, but 
  1010.         who knows maybe some of them will be needed...
  1011.  
  1012.       ■ When using C/ASM written code try to use Clipper VMM system as less 
  1013.         as possible because it requires additional allocations of memory 
  1014.         which are impossible to release until is specifically told by your 
  1015.         C/ASM program.
  1016.  
  1017.     - make as much as possible of free memory for Clipper program.
  1018.  
  1019.       ■ Use MS DOS 5.0 (or DR DOS 6.0 but there are known compatibility 
  1020.         problems of DR DOS with MS DOS which can affect any application) with 
  1021.         HIMEM.SYS and DOS=HIGH or with something providing UMB and load 
  1022.         everything high that can be loaded high.
  1023.  
  1024.       ■ Don't make unneeded FILES=, BUFFERS=, STACKS=, FCBS= allocations
  1025.         in CONFIG.SYS, for network environment can be told
  1026.  
  1027.         FILES= can be 8 in Novell Netware because FILE HANDLES= in NET.CFG
  1028.             are more important
  1029.         BUFFERS= can be 8 in any Network because buffers will not be used
  1030.             in networking access and therefore are relevant. Every buffer
  1031.             needs own memory for allocation. BUFFERS are anyway good in
  1032.             multiplications of at least four. If BUFFERS= is possible to
  1033.             move in EMS, HIGH memory do so (HIBUFFERS, BUFFERS=/X ...)
  1034.         STACKS=0,0 always. Nobody needs additional STACKs from MS DOS and
  1035.             some resident programs are requiring this anyway. Can save
  1036.             some space
  1037.         FCBS=at absolute possible minimum (version of DOS dependent)
  1038.  
  1039.       ■ Use replacements of COMMAND.COM like 4DOS (or NDOS) which are using
  1040.         only about 3KB of memory for COMMAND.COM and loading rest in EMS,XMS
  1041.         or just leaving as overlay on disk. I'm using 4DOS already several
  1042.         years and it's fully compatible COMMAND.COM replacement which cannot
  1043.         cause any troubles to any programs.
  1044.  
  1045.       ■ Do not use relevant device drivers like ANSI.SYS in system where
  1046.         nothing with ANSI will be used, COUNTRY.SYS when nobody needs COUNTRY 
  1047.         support, EGA.SYS, DRIVER.SYS or so. Every device driver needs memory 
  1048.         which can be handy for Clipper program. If those drivers are needed,
  1049.         use HIGHDEVICE, DEVICEHIGH or so for loading them to available high
  1050.         memory to save conventional memory for Clipper program.
  1051.  
  1052.       ■ Do not load relevant TSR programs like FASTOPEN in network, caching 
  1053.         software in network, DOSKEY when user will not be using DOS command 
  1054.         line at all because will walk whole day in menu. All neccesary TSR 
  1055.         programs is again good to load high (when possible)
  1056.  
  1057.       ■ Don't load relevant parts of network drivers. When nobody needs 
  1058.         NETBIOS emulation don't load it in Novell network. When nobody needs 
  1059.         SPX and Diagnostic communication don't load those parts of IPXODI 
  1060.         (when using DOS ODI drivers)
  1061.  
  1062.       ■ Use DOS ODI drivers instead of IPX/NETX in Novell Netware because 
  1063.         it's offering less memory usage and can even be reduced by excluding 
  1064.         mentioned SPX/Diagnostic part.
  1065.  
  1066.       ■ Use memory managers software like QEMM, QEMM386, QRAM, 386MAX, 
  1067.         BLUEMAX, NETROOM, HIDOS with possibility of creating up to 300KB of 
  1068.         HIGH memory for loading of ALL used TSR programs, device drivers, 
  1069.         files, buffers, fcbss. With programs like this can complete 
  1070.         workstation in DOS 5.0 really end in nearly 640KB free after loading 
  1071.         all programs including network drivers.
  1072.  
  1073.       ■ Use memory managers providing EMS memory (QEMM, EMM386, 386MAX, 
  1074.         NETROOM and others) which can then be used by Clipper paging and 
  1075.         overlaying system. It can help in speed increase of CLipper 
  1076.         application and also in some memory savings because of more accessible 
  1077.         memory.
  1078.  
  1079. ┌╖  That stupid hanging SHIFT key no my keyboard!
  1080. ╘╝
  1081.     In most from the networks is happening that SHIFT key is sticking ON
  1082.     even it's not really pressed. It's not problem of hardware, it's problem
  1083.     of software. Redirection of keyboard interrupt routines can become too
  1084.     long that it can start loosing status informations. In Networks it's
  1085.     common problem. There are PATCH programs which will solve this and is
  1086.     therefore highly recommended to get them before complaining about this
  1087.     Clipper programmers which are messing my keyboard. Look for KBFIX, 
  1088.     KBDFIX, KEYBFIX, SHIFTFIX, INTFIX INTxxFIX and similar words when 
  1089.     scanning for this patch. It's for sure available in NOVLIB...
  1090.  
  1091.  
  1092. ┌╖  Data integrity problems are in most cases problem of hardware
  1093. ╘╝  Hardware CAN cause terrible problems which looks like software bug
  1094.  
  1095.     Believe or not, there were MANY cases of software-like problems which 
  1096.     were caused by hardware problems, therefore following is a list to check 
  1097.     when problems exist but all other possibilities are already checked out.
  1098.  
  1099.     -   faulty network card in server or in workstation
  1100.  
  1101.         ANY faulty network card which is successfully working for common
  1102.         DOS tasks can fail under heavy Clipper load. It can fail most easy 
  1103.         because of amount of transferred data which Clipper applications 
  1104.         normally does. Any network MUST have possibility to CHECK network 
  1105.         cards for transferring errors. In normal cases must LAN have 100% 
  1106.         error free transfer between workstation and server. If it's not true 
  1107.         for some from network cards then replace them for sure.
  1108.  
  1109.     -   memory problems of workstation or server
  1110.  
  1111.         Because of heavy user of memory by Clipper application can easily 
  1112.         happen that faulty memory chip is not failing under normal 
  1113.         conditions, but only with Clipper programs (using for example EMS 
  1114.         memory somewhere at end of memory). If Parity error is not generated 
  1115.         wrong information can be obtained from memory and then used.
  1116.  
  1117.         Weak memory chips (SIMMs or SIPPs) are often successfully working with
  1118.         programs like MS DOS and are even able to pass initial memory test of 
  1119.         your computer (anyway this is not real test as it should be), but are
  1120.         visible under programs really checking memory (like CHECKIT). 
  1121.         Sometime computer MUST run longer time to get overheated a bit and 
  1122.         then test can be made to see problem.
  1123.  
  1124.     -   conflict in memory or in hardware
  1125.  
  1126.         Believe me that technicians installing network cards on IRQ2 are 
  1127.         still between us (IRQ2 is used in EVERY AT computer for all IRQs 
  1128.         8 till 15 and therefore is NOT free for network card). Computer
  1129.         or server with like this installed card WILL work. Will work
  1130.         slower and will have reliability problem in some cases because at
  1131.         least HARDDISK controller will be located between IRQ8 till IRQ15 and
  1132.         therefore IRQ2 will be shared by TWO devices.
  1133.  
  1134.         ANY conflict of hardware or software (like non deallocated ROM for
  1135.         QEMM which must be) can be source of problems. If program is running
  1136.         OK on _one_ computer and WRONG on _other_ computer, then be sure
  1137.         it's not problem of program (in 99% cases) but problem of computer.
  1138.  
  1139.     -   conflict with resident software
  1140.  
  1141.         There are MANY resident program which can cause problems for not only 
  1142.         Clipper application. One example should be USER.COM from LANSIGHT 
  1143.         software. When this resident program is loaded, Clipper applications
  1144.         acts like mad program, crashing in unpredictable moment or smashing 
  1145.         your database files. Therefore be always careful what TSR is loaded. 
  1146.         Test problematic program also on PURE MS DOS loaded computer. 
  1147.  
  1148.     -   bad sector on your server
  1149.  
  1150.         There MAY be problem for example in Novell Netware server that sector
  1151.         which is BAD is _not_ marked as bad and is used again and again. It's
  1152.         hard to understand how this can be happening, but i'm suspecting that 
  1153.         HotFix on some servers can be full (or off) and server can still run
  1154.         without someone notice it. In this case your database files will get
  1155.         corrupted on network, but will run fine in local disk or on other 
  1156.         volume. What can also make problems is:
  1157.  
  1158.         ■ too old version of disk driver
  1159.         ■ IDE (ISA) disk with bad driver or wrong setup in CMOS
  1160.         ■ disk which has ON-BOARD cache memory (like some Seagates) and
  1161.           this memory is not switched OFF. In server there MAY NOT be
  1162.           onboard cache memory on harddisk!
  1163.         ■ NLM which is responsible for disk/io operations is not well
  1164.           in good health
  1165.         
  1166.  
  1167. ┌╖  PURE MS DOS loaded computer is best place for testing your software if
  1168. ╘╝  any problems are out.
  1169.  
  1170.     In most cases computers on which your programs will run are filled with
  1171.     different configuration. That means that sometime configuration of 
  1172.     computer (hardware, software, TSR, DOS versions) can be causing problems. 
  1173.     To see if that's the case i have used BOOTSYS program which allows me 
  1174.     boot different configuration of my 386/40 for testing. One from them can 
  1175.     be called PURE MS DOS test configuration. It looks like this:
  1176.  
  1177.         CONFIG.SYS
  1178.             FILES=20
  1179.             BUFFERS=16
  1180.             DOS=HIGH
  1181.             DEVICE=C:\HIMEM.SYS
  1182.             STACKS=0,0
  1183.             SHELL=C:\COMMAND.COM /E:768 /P
  1184.  
  1185.         AUTOEXEC.BAT
  1186.             @ECHO OFF
  1187.             PROMPT $P$G
  1188.             \DOSODI\LSL
  1189.             \DOSODI\EXP16
  1190.             \DOSODI\IPXODI
  1191.             \DOSODI\NETX
  1192.             F:
  1193.             LOGIN
  1194.         
  1195.         NET.CFG
  1196.             FILE HANDLES=100
  1197.  
  1198.     See, NOTHING TSR loaded, NO device drivers at all. NO SETVER.EXE (anyway
  1199.     why to use it when all must be already DOS 5.0 aware). Just load MS DOS
  1200.     and then DOS ODI network drivers and log into network. NO EMS memory. 
  1201.     For more PURE configuration can be HIMEM.SYS and DOS=HIGH removed and
  1202.     network drivers not loaded and application tested from local harddisk.
  1203.  
  1204.     With this configuration one can be sure to eliminate ALL drivers, TSR,
  1205.     additions to your BIOS or VIDEO BIOS and test Clipper application.
  1206.  
  1207.     IF THIS is working and others are not? Look for configuration problems..
  1208.  
  1209. ┌╖  What about this SET magic of my Novell Netware 3.11 server, isn't good
  1210. ╘╝  to try to tune it?
  1211.  
  1212.     Novell Netware 3.11 operating system is selfconfiguring itself against 
  1213.     needs from workstations and server. In many cases is good anyway to tune 
  1214.     server manually for better performance, or at least take a look what's 
  1215.     going on. Following is list of all SET parameters which CAN be related
  1216.     to SPEED of Clipper applications.
  1217.  
  1218.     ■ Maximum Concurrent Disk Cache Writes
  1219.  
  1220.         Increase for WRITING having better performance
  1221.         Decrease for READING having better performance
  1222.  
  1223.     ■ Dirty Disk Cache Delay Time
  1224.  
  1225.         Increase for Small writes having better performance
  1226.         Decrease for better security of data (are sooner written to disk)
  1227.             but with performance going down
  1228.  
  1229.     ■ Dirty Directory Cache Delay Time
  1230.  
  1231.         Increase for better performance and less data security
  1232.         Decrease for better security of data, but slows down
  1233.  
  1234.     ■ Maximum Concurrent Directory Cache Writes
  1235.  
  1236.         Increase for better writing
  1237.         Decrease for better reading
  1238.  
  1239.     ■ Directory Cache Allocation Wait Time
  1240.  
  1241.         Increase will slow down directory accessing time
  1242.         Decrease will FAST directory accessing time
  1243.  
  1244.     ■ Directory Cache Buffer Non Referenced Delay
  1245.         
  1246.         Increase will give faster access to directories
  1247.         Decrease will slow access to directories, but will give more 
  1248.             memory for other server tasks
  1249.  
  1250.     ■ Maximum Directory Cache Buffers
  1251.         
  1252.         Increase will give better directory access
  1253.         Decrease when memory in server is required, slows directory access
  1254.  
  1255.     ■ Minimum Directory Cache Buffers
  1256.  
  1257.         Increase will give better initial directory access to server,
  1258.             it's effective only for time of start of server
  1259.  
  1260.     ■ Immediate Purge Of Deleted Files
  1261.         
  1262.         if ON, all deleted files are immediately removed from server, 
  1263.             SALVAGE utility has not effect after. Can make server MUCH
  1264.             faster, but make impossible to undelete files
  1265.  
  1266.     ■ Turbo FAR Re-Use Wait Time
  1267.  
  1268.         Increase is good for database files because Turbo-Fat is kept
  1269.             longer in memory. But needs more server memory
  1270.         Decrease saves memory of server
  1271.  
  1272.     ■ Minimum File Delete Wait Time
  1273.  
  1274.         How long file MUST stay (may not be marked ready for Purge).
  1275.             Can help with keeping deleted files.
  1276.  
  1277.     ■ File Delete Wait Time
  1278.  
  1279.         After how long file is marked ready for purge and may be 
  1280.             therefore automatically purges from disk. Can help to 
  1281.             manage deleted files.
  1282.  
  1283.     ■ Maximum Subdirectory Tree Depth
  1284.  
  1285.         Automatically it's 25 directories level maximum which Netware
  1286.             will allow. If your Clipper application runs with more
  1287.             directories level, increase this number.
  1288.  
  1289.     ■ NCP File Commit
  1290.  
  1291.         When it's ON (default) any application calling File Commit NCP  
  1292.             command WILL make HARD flush of data from memory to harddisk
  1293.             of server. Set it to OFF for better performance of server when
  1294.             CLipper application is using too much of DBCOMMIT() calls.
  1295.  
  1296.     ■ Console Display Watchdog Logout
  1297.  
  1298.         Can help you to determine WHY your programs are disconnected from
  1299.             network without visible reason.
  1300.  
  1301.     ■ Maximum Packet Receive Buffer
  1302.  
  1303.         It's limiting number of receive buffers for data from workstations.
  1304.             In case of network error without hardware cause increase this
  1305.             number because server cannot server all your workstation 
  1306.             requests.
  1307.  
  1308.     ■ Maximum Record Locks Per Connection
  1309.  
  1310.         Defaults to 500 and means that your program can make maximum of
  1311.             500 records locked in your databases. If Clipper application is
  1312.             receiving errors of Record locking kind, increase this number.
  1313.             It's PER WORKSTATION, not FOR WHOLE NETWORK.
  1314.  
  1315.     ■ Maximum File Locks Per Connection
  1316.  
  1317.         Default to 250 and means that your program can lock maximum of
  1318.             250 files (by flock()). It's quite enough because it's also
  1319.             real maximum of files available from network at all.
  1320.  
  1321.     ■ Maximum Record Lock
  1322.  
  1323.         Defaults to 20000 and means maximum of record locks per whole server
  1324.             from all workstation. By default it's space for 40 workstations
  1325.             using full available 500 records lock each. It should be enough,
  1326.             otherwise can be increased. Decreasing can save some server
  1327.             memory and keep better performance.
  1328.  
  1329.     ■ Maximum File Lock
  1330.  
  1331.         Default to 10000 and means maximum of file locks per whole server 
  1332.             from all workstations. By default it's space for 40 workstations
  1333.             using full available 250 file locks each. It should be enough,
  1334.             otherwise can be increased. Decreasing can save some server
  1335.             memory and keep performance better.
  1336.  
  1337.     ■ Auto TTS Backout Flag
  1338.  
  1339.         When ON (default) server will automatically after crash backout all
  1340.             active transaction during start. When OFF supervisor must react
  1341.             for server's questions.
  1342.  
  1343.     ■ TTS Abort Dump Flag
  1344.  
  1345.         When ON will create every time TTS$LOG.ERR file in root of volume.
  1346.             This file can log all transactions for analyzing.
  1347.  
  1348.     ■ Maximum Transactions
  1349.  
  1350.         Maximum number of transactions per server from all workstations. 
  1351.             Should be enough, but can be changed.
  1352.  
  1353.     ■ Enable Disk Read After Write Verify
  1354.  
  1355.         Can make server as twice fast when it's OFF, but then there will be
  1356.             NO verification of data after writing which can lead in data 
  1357.             integrity problems. In disk with own READ/WRITE verify on board
  1358.             it's possible switch this OFF.
  1359.  
  1360.     ■ Maximum outstanding NCP searches
  1361.  
  1362.         When corrupted or invalid directories are encountered in some 
  1363.             application is good time to increase this.
  1364.  
  1365.     ■ Allow Unencrypted Passwords
  1366.  
  1367.         Novell 3.11 introduced all passwords as encrypted when travelling
  1368.             through network. If 2.x server with non-update utilities is
  1369.             in the same network as 3.11 server is good to set this to ON.
  1370.  
  1371.     ■ Maximum Service processes
  1372.  
  1373.         Increasing makes better performance
  1374.         Decreasing slows down, but gives more memory for other server tasks.
  1375.  
  1376.     Most from those SET command should be checked once a while in 3.11 server
  1377.     via MONITOR program where are visible most important setting. This check
  1378.     should include check for:
  1379.  
  1380.                                 Minimum     Maximum     Sample Reality
  1381.     Service Processes                         20               4
  1382.     Packet Receive Buffers      10           100              10
  1383.     Directory Cache Buffers     20           500             110
  1384.  
  1385.         In this sample is good time to start about thinking parameter called
  1386.         Minimum Directory Cache Buffers because it can fast up starting of
  1387.         server and users coming to access their directories. It can be inc-
  1388.         reased to 100 or 110. Other parameters are in order and nothing is
  1389.         near of maximum, therefore it has enough room to grow.
  1390.  
  1391.  
  1392. ┌╖  When the SPEED is main problem
  1393. ╘╝
  1394.     SPEED of Clipper application is main problem always and in network it's 
  1395.     one from most important moments. What to do for maximum speed of your
  1396.     program:
  1397.  
  1398.     -   make sure that network is enough fast. It can be done by checking
  1399.         transfer speed of your network by simply running SystemInfo from
  1400.         Norton Utilities set. Example numbers:
  1401.  
  1402.         Novell Netware 3.11, Ethernet 8bit card     280~300 KB/sec
  1403.         Novell NEtware 3.11, Ethernet 16bit card    320~370 KB/sec
  1404.         Novell Netware 2.2, Ethernet 16bit card     230~270 KB/sec
  1405.         Lantastic 4.01, Ethernet IDEAL condition    200~250 KB/sec
  1406.         Lantastic 4.01, Ethernet REAL condition     150~200 KB/sec
  1407.         Lantastic older versions                    50~100 KB/sec
  1408.         Novell Netware 3.11, Arcnet (2.5MB)         100~170 KB/sec
  1409.         Lan Manager, Ethernet                       100~150 KB/sec
  1410.         Lantastic 4.01, 2MB twisted pair             30~ 50 KB/sec
  1411.         Serial network (RS232C)                      10~ 30 KB/sec
  1412.  
  1413.         If your number are much lower than those it's time to thinking
  1414.         about:
  1415.  
  1416.         ■ network card is on wrong IRQ and is slowed down
  1417.         ■ network card is faulty and should be replaced
  1418.         ■ network drivers (Shell) is loaded high and therefore slow
  1419.           use standard one (like NETX) and don't load it high
  1420.         ■ network card should be upgraded from 8bit card to full
  1421.           16bit card when possible
  1422.         ■ computer itself is very slow
  1423.         ■ network card is using DMA or MEMORY technique of communication
  1424.           upgrade to better card using only IO and IRQ
  1425.         ■ server has problems with network card. In server it should
  1426.           be ALWAYS _very_ fast 16bit (minimally) card, otherwise
  1427.           whole network is slow
  1428.         ■ on Novell try to use BNETX for increasing of speed
  1429.         ■ Server is very short on memory and has not enough resources
  1430.           to react to network requests
  1431.         ■ Server is very slow (typical server should be at least 386/25)
  1432.         ■ Server has VERY slow disk or faulty controller or driver
  1433.         ■ There are wiring problem, check number of errors in card
  1434.           statistics or check connection between stations and recheck
  1435.           cabling. Weak connector, missing terminator, interference,
  1436.           not correct card can be reason for slow communication
  1437.         ■ upgrade your network version to something significantly faster
  1438.           and reliable (like Lantastic to Novell Netware, Novell Lite to
  1439.           Lantastic or Novell Lite to real Netware).
  1440.         ■ Upgrade your network topology and type. ARCNET is slower than
  1441.           Ethernet (2.5MB against 10MB) and so on.
  1442.  
  1443.     -   Make as much as memory available for your application
  1444.  
  1445.         This is covered somewhere else in this article, therefore go there.
  1446.         If Clipper application has not enough memory it must make more
  1447.         disk swapping and overlaying and therefore is slowing down
  1448.  
  1449.     -   Make EMS memory available for your Clipper application
  1450.  
  1451.         Clipper 5.01 can use EMS memory for overlays and data, therefore
  1452.         enough of EMS (2MB at least) can make significant difference in
  1453.         speed - disk overlay is not used and EMS is MUCH faster.
  1454.  
  1455.     -   Place temporary files on RAMDISK or HARDDISK instead of network.
  1456.  
  1457.         If your network is not faster than your harddisk, try to point TEMP
  1458.         files to harddisk (or ramdisk). It's faster and also network traffic
  1459.         will be much smaller
  1460.  
  1461.     -   When linking application try to move often used modules in ROOT 
  1462.         instead of letting overlay them. It can have impact on using of
  1463.         memory, but can make application MUCH faster. When for example is
  1464.         your application using function CHECKIT() every start of MENU on
  1465.         screen, then maybe place it to ROOT and it will not be loaded 
  1466.         again and again over. But think about memory usage of course...
  1467.  
  1468.     -   place your .EXE file on your local harddisk or RAMDISK and access
  1469.         only data files if it is possible. .EXE will be loaded faster from
  1470.         your disk and also all reading of overlaid part will be faster
  1471.  
  1472.     -   make sure that your machine is running at highest possible speed.
  1473.         Most of AT machines have speed switch on chassis or possibility to use
  1474.         CTRL ALT + (big gray plus, not the small one) for switching to high
  1475.         speed. Use some SystemInfo or SPEED utility to see if it's really
  1476.         running fastest as can. 
  1477.  
  1478.     -   Do not expect that 8088 or 8086 machines will be speed deamons for
  1479.         Clipper application. It will be VERY slow. Average SLOW AT286/12Mhz
  1480.         is still 4 times faster than average 808x machine. Upgrade those 
  1481.         machines as fast as possible or use them for other jobs (like
  1482.         print servers they are of great use for matrix printers!). 
  1483.  
  1484.     -   When upgrading 8088, 8086 or 80286 machines it's good to upgrade them
  1485.         at least to 80386SX/16Mhz with some 2MB or 4MB of memory. 
  1486.  
  1487.     -   Make sure that your computer has not:
  1488.  
  1489.         ■ slow harddisk which can make lot of troubles
  1490.         ■ slow harddisk controller
  1491.         ■ slow video card. Upgrade all those CGA, MCGA and HERCULES cards to
  1492.           VGA and all will be better in displaying speed
  1493.         ■ slow memory chips requiring additional WAIT STATES
  1494.         ■ keyboard in bad mode because it will work, but slowing down
  1495.         ■ faulty card in system bus because it will slow down all I/O
  1496.           operations
  1497.  
  1498.     -   make sure that your program is written as much effective as possible
  1499.         because that's main point of many programs running very slow. Some
  1500.         tips for this:
  1501.  
  1502.         - do not use PRIVATE or PUBLIC
  1503.         - use your indexes as good as possible. When one can make SEEK
  1504.           instead of skipping through database, it's much faster
  1505.         - use DBFSIX replacement of DBFNTX because it's much faster
  1506.           in network and offers much more for optimization
  1507.         - use MACH6 query optimizer for your database operations
  1508.         - EXTENDBASE software for your server should help also
  1509.         - don't generate unneeded files
  1510.         - optimize your databases to not have so much of them without
  1511.           reason
  1512.         - pack sometime .DBT files and .DBF files because if file is
  1513.           too big, it's slower
  1514.         - reports generated from your files which are not ORDER 
  1515.           dependent is good to generate with SET ORDER TO 0 because
  1516.           it will save time to access your index and also will reduce
  1517.           network traffic
  1518.         - SUBNTX or DBFSIX is also handy for creating subsets of
  1519.           index files
  1520.  
  1521. ┌╖  OOPS and what about those terrible problems with indexes
  1522. ╘╝
  1523.     Most from us experienced already some 1210 Internal errors or index 
  1524.     corruptions. There is NOT most probably bug in Clipper 5.01 way of
  1525.     handling .NTX files, but there WAS bug in 5.0 version causing corruptions
  1526.     in case of BIG applications. Most from index corruption are related to:
  1527.  
  1528.     -   index key expression is NOT STABLE. It means it HAS NOT EXACTLY the
  1529.         same size EVERY time it's invoked. TRIM() functions are suicide when
  1530.         used in index key. Remember that index key MUST have always the same
  1531.         length which MUST be the same also when EMPTY parameters are passed to
  1532.         index key (that's a way how Clipper is making initial size for 
  1533.         generating a index files).
  1534.  
  1535.     -   index key expression is NOT UNIQUE. It means it's RELATED to some
  1536.         other WORK AREAS or FUNCTIONS which can give different results
  1537.         when making and when updating index. Be absolutely sure that there
  1538.         is NO WAY how to make INDEX ON ADRES->NAME+DATA->CODE even when
  1539.         SET RELATION is invoked between ADRES and DATA. No discussion about
  1540.         this, it's even documented in Clipper documentation
  1541.  
  1542.     -   Index files are not opened in THE SAME order. It's VERY important
  1543.         that two programs using the same .DBF with the same .NTX (or any
  1544.         other) file is opening them in the same order. What is therefore
  1545.         wrong is for example:
  1546.  
  1547.         App1    SET INDEX TO NAME,LEVEL,CODE
  1548.         App2    SET INDEX TO NAME,CODE,LEVEL
  1549.  
  1550.         In this example most sure LEVEL and CODE are two indexes ready for
  1551.         become corrupted. Why? Because Clipper will update index keys in
  1552.         order they are defined in application and when two Applications 
  1553.         will come to LEVEL and CODE it will get updated in different order
  1554.         and can destroy index.
  1555.  
  1556.     -   Index file are not opened always when database is updates. It's 
  1557.         again VERY important to open ALL index files and have them OPEN
  1558.         at moment database is updates. Don't try to stick on rule that
  1559.         'when index key related fields are updated', stick on rule that
  1560.         ALWAYS when database is updated. Therefore this is wrong:
  1561.  
  1562.         App1    SET INDEX TO NAME,LEVEL,CODE
  1563.         App2    SET INDEX TO NAME,LEVEL
  1564.  
  1565.         CODE index in this case is subject of destruction which will be
  1566.         manifested by missing keys from index because APP2 will not 
  1567.         update correctly this index (because it's not open).
  1568.  
  1569.     -   if DBFSIX is your horse for race, then don't forget to update to
  1570.         latest revision (which is 2:30am) and which is fixing few little
  1571.         index related problems finally.
  1572.  
  1573.  
  1574. A word from author───┐
  1575. ─────────────────────┘
  1576.  
  1577.     Final word. I tried in two days compile as much as knowledge which i was
  1578.     keeping in my head and occasionally just copying out to Compuserve Mail as
  1579.     answers to most common question. I'm sure that i forget something that
  1580.     might be interesting or important, therefore if it's your experience or
  1581.     knowledge that can be added into this Network Guide for Clipper, please
  1582.     feel free to write me or tell me (CIS ID is 100064,2343 and i'm checking
  1583.     mail every working day). I can later release newer versions with updates.
  1584.  
  1585.     Finally for those speaking English as mother tongue. I'm CZECH and i'm
  1586.     working now in The Netherlands (which anyway speaks Dutch) and therefore
  1587.     my English for sure look funny (formulation) and must have many mistakes
  1588.     or misused word. Take a fun i have it also. Anyone wishing make language
  1589.     correction of this text is anyway welcome.
  1590.  
  1591.     And please don't write angry letter or angry comments about something
  1592.     you don't agree with. It can be in many cases.
  1593.  
  1594.     Daniel
  1595.  
  1596.     100064,2343 Compuserve
  1597.     2:285/608@FidoNet
  1598.     (31)-10-4157141 FAX to NETCONSULT/DANIEL
  1599.     (31)-10-4157140 VOICE to NETCONSULT/DANIEL
  1600.     
  1601.